<script lang="ts" setup>
import type { MenuInfo } from 'ant-design-vue/es/menu/src/interface';

import type { HeaderEmits, HeaderProps } from '../types';

import { computed, ref, useSlots, watch } from 'vue';

import { useNamespace } from '@vben/hooks';

import { useDebounceFn } from '@vueuse/core';
import {
  Dropdown,
  InputSearch,
  Menu,
  MenuDivider,
  MenuItem,
} from 'ant-design-vue';

import { BasicTitle } from '#/components/basic';
import { Icon } from '#/components/icon';
import { $t } from '#/locales';

import { ToolbarEnum } from '../types';

defineOptions({
  name: 'BasicTreeHeader',
  inheritAttrs: false,
});

const props = withDefaults(defineProps<HeaderProps>(), {
  helpMessage: '',
  title: '',
  toolbar: false,
  checkable: false,
  search: false,
  searchText: '',
  checkAll: undefined,
  expandAll: undefined,
  // 工具栏是否显示 层级关联
  toolbarStrictly: true,
  checkStrictly: undefined,
});

const emit = defineEmits<HeaderEmits>();

const searchValue = ref('');
const { b } = useNamespace('tree-header');

const slots = useSlots();

const getInputSearchCls = computed(() => {
  const titleExists = slots.headerTitle || props.title;
  return [
    'mr-1',
    'w-full',
    {
      'ml-5': titleExists,
    },
  ];
});

const toolbarList = computed(() => {
  const { checkable, toolbarStrictly } = props;

  // 展开和收起
  const expandList = [
    { label: $t('component.tree.expandAll'), value: ToolbarEnum.EXPAND_ALL },
    {
      label: $t('component.tree.unExpandAll'),
      value: ToolbarEnum.UN_EXPAND_ALL,
    },
  ];

  // 全选和取消全选
  const selectList = checkable
    ? [
        { divider: true },
        {
          label: $t('component.tree.selectAll'),
          value: ToolbarEnum.SELECT_ALL,
        },
        {
          label: $t('component.tree.unSelectAll'),
          value: ToolbarEnum.UN_SELECT_ALL,
        },
      ]
    : [];

  function test() {
    return props.checkStrictly
      ? {
          label: $t('component.tree.checkStrictly'),
          value: ToolbarEnum.CHECK_STRICTLY,
        }
      : {
          label: $t('component.tree.checkUnStrictly'),
          value: ToolbarEnum.CHECK_UN_STRICTLY,
        };
  }

  // checkable 状态下节点选择完全受控（父子节点选中状态不再关联）
  const strictlyList =
    toolbarStrictly && checkable ? [{ divider: true }, test()] : [];

  return [...expandList, ...selectList, ...strictlyList];
});

function handleMenuClick(info: MenuInfo) {
  const { key } = info;
  switch (key) {
    case ToolbarEnum.CHECK_STRICTLY: {
      emit('strictlyChange', false);
      break;
    }
    case ToolbarEnum.CHECK_UN_STRICTLY: {
      emit('strictlyChange', true);
      break;
    }
    case ToolbarEnum.EXPAND_ALL: {
      props.expandAll?.(true);
      break;
    }
    case ToolbarEnum.SELECT_ALL: {
      props.checkAll?.(true);
      break;
    }
    case ToolbarEnum.UN_EXPAND_ALL: {
      props.expandAll?.(false);
      break;
    }
    case ToolbarEnum.UN_SELECT_ALL: {
      props.checkAll?.(false);
      break;
    }
  }
}

function emitChange(value: string): void {
  emit('search', value);
}

const debounceEmitChange = useDebounceFn(emitChange, 200);

watch(
  () => searchValue.value,
  (v) => {
    debounceEmitChange(v);
  },
);

watch(
  () => props.searchText,
  (v) => {
    if (v !== searchValue.value) {
      searchValue.value = v;
    }
  },
);
</script>
<template>
  <div :class="b()" class="flex items-center px-2 py-1.5">
    <slot name="headerTitle" v-if="slots.headerTitle"></slot>
    <BasicTitle :help-message="helpMessage" v-if="!slots.headerTitle && title">
      {{ title }}
    </BasicTitle>
    <div
      class="flex flex-1 cursor-pointer items-center justify-self-stretch"
      v-if="search || toolbar"
    >
      <div :class="getInputSearchCls" v-if="search">
        <InputSearch
          :placeholder="$t('common.searchText')"
          size="small"
          allow-clear
          v-model:value="searchValue"
        />
      </div>
      <Dropdown @click.prevent v-if="toolbar">
        <Icon icon="ion:ellipsis-vertical" />
        <template #overlay>
          <Menu @click="handleMenuClick">
            <template v-for="item in toolbarList" :key="item.value">
              <MenuDivider v-if="item.divider" />
              <MenuItem
                v-else
                v-bind="{ key: item.value }"
                :disabled="item.disabled"
              >
                {{ item.label }}
              </MenuItem>
            </template>
          </Menu>
        </template>
      </Dropdown>
    </div>
  </div>
</template>
